//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once

#include "list.h"
#include "fixed_allocator.h"


FC_NAMESPACE_BEGIN


template <class T, size_t N, class Allocator>
class fixed_list : public list<T, Allocator>
{
public:
	typedef fixed_list<T, N, Allocator>					this_type;
	typedef list<T, Allocator>							base_type;
	typedef typename base_type::node_type				node_type;
	typedef typename base_type::allocator_type			allocator_type;

	using base_type::m_allocator;
	using base_type::m_size;

	enum
	{
		buffer_size_n_bytes = N * sizeof(node_type),
		buffer_alignment = FC_ALIGNOF(node_type)
	};

	typedef aligned_buffer<buffer_size_n_bytes, buffer_alignment> buffer_type;

	fixed_list()
		: base_type()
		{
			init();
		}

	explicit fixed_list( const allocator_type& alloc )
		: base_type(alloc)
		{
			init();
		}

	template <class InputIterator>
	fixed_list( InputIterator first, InputIterator last )
		: base_type()
		{
			init();
			base_type::assign( first, last );
		}

	fixed_list( const fixed_list& l )
		: base_type()
		{
			init();
			base_type::assign( l.begin(), l.end() );
		}

	this_type& operator =( const this_type& x )
	{
		base_type::operator =(x);
		return *this;
	}

	bool has_overflowed() const
	{
		//todo: fix this
		return !m_allocator.can_allocate();
	}

	void reset()
	{
		if( size() != 0 )
			base_type::clear();

		init();
	}

	void init()
	{
		m_allocator.init( m_buffer.data, sizeof(m_buffer.data), sizeof(node_type), FC_ALIGNOF(node_type) );
	}

	T* get_buffer() const
	{
		return (T*)m_buffer.data;
	}

protected:
	buffer_type m_buffer;

};



FC_NAMESPACE_END
